﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace Koopakiller.Numerics.Resources
{
    /// <summary>
    /// Initializes new instances of exception class with localized strings.
    /// </summary>
    public static class ExceptionHelper
    {
        /// <summary>
        /// Initializes a new <see cref="System.ArgumentNullException"/>.
        /// </summary>
        /// <param name="parameter">The name of invalid parameter.</param>
        /// <param name="name">The name of the string resource.</param>
        /// <param name="insertValues">The values to insert in the message.</param>
        public static ArgumentNullException GetArgumentNull(string parameter, string name, params string[] insertValues)
        {
            return new ArgumentNullException(parameter, string.Format(strings["ArgNull_" + name], insertValues));
        }
        /// <summary>
        /// Initializes a new <see cref="System.ArgumentOutOfRangeException"/>.
        /// </summary>
        /// <param name="parameter">The name of invalid parameter.</param>
        /// <param name="name">The name of the string resource.</param>
        /// <param name="insertValues">The values to insert in the message.</param>
        public static ArgumentOutOfRangeException GetArgumentOutOfRange(string parameter, string name, params string[] insertValues)
        {
            return new ArgumentOutOfRangeException(parameter, string.Format(strings["ArgOutRang_" + name], insertValues));
        }
        /// <summary>
        /// Initializes a new <see cref="System.ArgumentDifferentException"/>.
        /// </summary>
        /// <param name="parameter1">The name of the first invalid parameter.</param>
        /// <param name="parameter2">The name of the second invalid parameter.</param>
        /// <param name="parameter1">The value of the first invalid parameter.</param>
        /// <param name="parameter2">The value of the second invalid parameter.</param>
        /// <param name="name">The name of the string resource.</param>
        /// <param name="insertValues">The values to insert in the message.</param>
        public static ArgumentDifferentException GetArgumentDifferent(string parameter1, string parameter2, object value1, object value2, string name, params string[] insertValues)
        {
            return new ArgumentDifferentException(string.Format(strings["ArgOutRang_" + name], insertValues), parameter1, parameter2, value1, value2);
        }

        /// <summary>
        /// Load the resources.
        /// </summary>
        static ExceptionHelper()
        {
            try
            {
                string lanCode = string.Empty;
                switch (CultureInfo.CurrentCulture.TwoLetterISOLanguageName)//language of system
                {
                    //! insert supported languages
                    case "de": lanCode = "de"; break;
                    default: lanCode = "en"; break;
                }

                var s = Assembly.GetExecutingAssembly().GetManifestResourceStream(@"Koopakiller.Numerics.Resources.ExceptionStrings.xml");//load file from resources
                StreamReader sr = new StreamReader(s);

                strings = XDocument.Load(sr).Root
                                   .Elements("string")
                                   .ToDictionary(x => x.Attribute("type").Value + "_" + x.Attribute("id").Value,
                                                 x => x.Element(lanCode).Value);
            }
            catch (Exception ex)
            {
                if (Debugger.IsAttached)
                    Debugger.Break(); //! Error, find and correct them!
                throw new NotImplementedException("Unknown Error", ex);
            }
        }

        /// <summary>
        /// Contains the localized resources.
        /// </summary>
        static Dictionary<string, string> strings;
    }
}
